/*******************************************************************************
 * Copyright (c) 2002 Boris Pruessmann and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Common Public License v0.5
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v05.html
 * 
 * Contributors:
 *    Boris Pruessmann - Initial implementation.
 ******************************************************************************/
package net.sourceforge.perforce.ui.action;

import net.sourceforge.perforce.core.PerforceException;
import net.sourceforge.perforce.core.api.IPerforceServer;
import net.sourceforge.perforce.core.api.IResolveResult;
import net.sourceforge.perforce.core.api.ResolveTypeEnum;
import net.sourceforge.perforce.core.internal.P4TeamProvider;
import net.sourceforge.perforce.core.resources.IP4File;
import net.sourceforge.perforce.core.resources.RemoteResource;
import net.sourceforge.perforce.ui.P4ResolveEditorInput;
import net.sourceforge.perforce.ui.PerforceCompareEditorInput;
import net.sourceforge.perforce.ui.PerforceResourceEditionNode;
import net.sourceforge.perforce.ui.PerforceResourceNode;
import net.sourceforge.perforce.ui.PerforceUIPlugin;
import net.sourceforge.perforce.ui.internal.Policy;
import org.eclipse.compare.CompareEditorInput;
import org.eclipse.compare.CompareUI;
import org.eclipse.compare.internal.CompareUIPlugin;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.action.IAction;
import org.eclipse.swt.widgets.Display;
import org.eclipse.team.core.TeamException;

/**
  * @version $Revision: 202 $
  * @author  <a href="mailto:bpruessmann@users.sourceforge.net">Boris Pruessmann</a>
  */
public class ResolveManuallyAction extends P4FileAction 
{
	// ------------------------------------------------------------------------------ Public Methods

	/** @see IActionDelegate#run(IAction) */
	public void run(IAction action) 
	{
		try
		{
			triggerCompareUI();
			
			IP4File[] files = getSelectedPerforceFiles();
			Policy.assertTrue(files.length == 1);
			
			IWorkspaceRoot root = PerforceUIPlugin.getWorkspace().getRoot();
			IFile file = root.getFileForLocation(files[0].getLocation());
			if (!file.isSynchronized(IResource.DEPTH_INFINITE))
			{
				file.refreshLocal(IResource.DEPTH_INFINITE, null);
			}
													
			IPerforceServer server = files[0].getServer();
			
			// Get Ancestor
			RemoteResource ancestorResource = getAncestor(file, server);
			Policy.assertNotNull(ancestorResource);
			
			// Get Remote
			P4TeamProvider provider = P4TeamProvider.getProvider(file);
			RemoteResource remoteResource =	provider.getRemoteTree(file, "#head", null);
			
			PerforceCompareEditorInput input = 
				new P4ResolveEditorInput(
					new PerforceResourceNode(file), 
					new PerforceResourceEditionNode(remoteResource), 
					new PerforceResourceEditionNode(ancestorResource));
			
			openCompareEditor(input);
		}
		catch (CoreException e)
		{
			handle(e);
		}
		catch (TeamException e)
		{
			handle(e);
		}
	}
	
	// --------------------------------------------------------------------------- Protected Methods

	/** @see PerforceAction#isEnabled() */
	protected boolean isEnabled() 
		throws PerforceException 
	{
		IP4File[] files = getSelectedPerforceFiles();
		if (files.length != 1)
		{
			return false;
		}
		
		IP4File file = files[0];
		if (!file.needsResolve())
		{
			return false;
		}
		
		IWorkspaceRoot root = PerforceUIPlugin.getWorkspace().getRoot();
		IFile eclipseFile = root.getFileForLocation(file.getLocation());
		if (eclipseFile == null || !eclipseFile.isAccessible())
		{
			return false;
		}
		
		return true;
	}
	
	// ----------------------------------------------------------------------------- Private Methods
		
	/** Called to retrieve the ancestor resource for the given file.
	  *
	  * @param file the file.
	  * @param server the perforce server.
	  * @return the ancestor resource.
	  * 
	  * @throws TeamException in case of an error.
	  */
	private RemoteResource getAncestor(IFile file, IPerforceServer server)
		throws TeamException 
	{
		P4TeamProvider provider = P4TeamProvider.getProvider(file);
		IResolveResult[] resolveResults = 
			server.resolve(
				file.getLocation().toOSString(), 
				ResolveTypeEnum.AUTOMATIC, 
				IPerforceServer.RESOLVE_SIMULATE);
		Policy.assertTrue(resolveResults.length == 1);
		
		int revision = resolveResults[0].getRevision().intValue() - 1;
		RemoteResource result =	provider.getRemoteTree(file, "#" + revision, null);    //$NON-NLS-1$
		
		return result;
	}
	
	/** Called to open the Compare Editor UI with the given input.
	  *
	  * @param input the input. 
	  */
	private void openCompareEditor(final CompareEditorInput input) 
	{
		Runnable runnable =
			new Runnable()
			{
				public void run() 
				{
					CompareUI.openCompareEditor(input);
				}
			};
		
		Display display = getShell().getDisplay();
		display.syncExec(runnable);
	}
	
	/** This method will trigger the load of the Compare Component within the display thread */
	private void triggerCompareUI()
	{
		Display display = getShell().getDisplay();
		display.syncExec(new Runnable()
		{
			/** @see java.lang.Runnable#run() */
			public void run() 
			{
				CompareUIPlugin.getDefault();
			}
		});
	}			
}
